/* GMClient.hh -- Cliente GEARMedula
 *
 * Copyright (C) 2008, Diogo F. S. Ramos <diogo.ramos@usp.br>
 * GEAR - Grupo de Estudos Avançados em Robótica
 * <http://www.sel.eesc.usp.br/gear>
 *
 * This file is part of GEARMedula.
 * 
 * GEARMedula is free software: you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation, version 3 of the
 * License.
 * 
 * GEARMedula is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see
 * <http://www.gnu.org/licenses/>.
 */

#ifndef GMCLIENT_HH_
#define GMCLIENT_HH_

#include <sys/socket.h>
#include <netinet/in.h>

#include <string>
#include <vector>

#include "RPCTranslator.hh"


/** Classe para trocar informações do campo.

    Esta classe deve ser utilizada primariamente pela Visão ou por
    qualquer peer que não precise controlar os robôs.
    
 */
class GMClient{
    int server_socket_;
    struct sockaddr_in server_socket_name_;
    char received_data_buffer_[ kBufferSize ];
    char sended_data_buffer_[ kBufferSize ];
    RPCTranslator rpc_translator_;

    int SendMessage();
    void SendCommand( MessageType message_type, std::vector<struct FieldContainer> arguments_passed );
    void ReceiveCommand( MessageType message_type, std::vector<struct FieldContainer> &arguments_passed );
    void ReceiveMessage();
    void DecodeReceivedMessage( MessageType message_type, std::vector<struct FieldContainer> &arguments_parsed);

    void InitSocketAddr( struct sockaddr_in *name, const char *hostname, uint16_t port);
public:
    GMClient();
    ~GMClient();

    /** Inicia o cliente.

        @param addr Endereço do servidor.

        @param port Porta em que o servidor esta escutando.

        @return Retorna 0 caso sucesso.
    */
    int Init( const std::string addr, const int port );

    /** Seta as informações do Field no GEARMedula.

        @param field Vetor com as informação de campo.

        @return Retorna 0 caso sucesso.       
     */
    int setField( const std::vector<float> field );

    /** Seta as informações de World no GEARMedula.

        @param world Vetor com as informações do mundo.
       
        @return Retorna 0 caso sucesso.
     */
    int setWorld( const std::vector<float> world );

    /** Enche o vetor field com as informações de campo retiradas do
        GEARMedula.

        @param &field Vetor field a ser preenchido.
       
        @return Retorna 0 caso sucesso.
    */
    int getField( std::vector<float> &field );
    
    /** Enche o vetor world com as informações de mundo retiradas do
        GEARMedula.

        @param &world Vetor world a ser preenchido.
       
        @return Retorna 0 caso sucesso.
    */
    int getWorld( std::vector<float> &world );

    /** <b>Não use!</b> <em>You have been warned.</em> */
    int SetVel( const int id, const float vx, const float vy, const float va );
    /** <b>Não use!</b> <em>You have been warned.</em> */
    int Kick( const int id, const int nivel );
    /** <b>Não use!</b> <em>You have been warned.</em> */
    int DribbleEnable(const int id, const bool enable );
    /** <b>Não use!</b> <em>You have been warned.</em> */
    int SayHello(const int id);
    /** <b>Não use!</b> <em>You have been warned.</em> */
    int RegisterRobotName(const int id, const std::string robot_name );
};

#endif	// GMCLIENT_HH_
